<template>
  <div class="app-container">
    <el-form :inline="true">
      <el-form-item>
        <el-button
          v-show="mList.length > 0"
          icon="el-icon-delete"
          type="danger"
          @click="mDel"
        >{{ $t('delete') }}
        </el-button>
      </el-form-item>
      <el-form-item v-if="sensor.sensorId">
        <el-button
          icon="el-icon-plus"
          type="primary"
          @click="showAdd"
        >{{ $t('add') }}
        </el-button>
      </el-form-item>
      <el-form-item>
        <el-button
          icon="el-icon-cpu"
          type="primary"
          @click="gotoSensor()"
        >{{ $t('sensor') }}
        </el-button>
      </el-form-item>
      <el-form-item>
        <el-button
          icon="el-icon-guide"
          type="primary"
          @click="gotoHistory"
        >{{ $t('history') }}
        </el-button>
      </el-form-item>
      <el-form-item>
        <el-button
          icon="el-icon-view"
          type="primary"
          @click="showSetting = true"
        >{{ $t('preview') }}
        </el-button>
      </el-form-item>
      <el-form-item>
        <el-button
          type="primary"
          icon="el-icon-menu"
          @click="gotoVisible"
        >{{ $t('visible') }}
        </el-button>
      </el-form-item>
      <el-form-item>
        <el-select
          v-model="sensorId"
          @change="sensorChange"
        >
          <el-option
            v-for="item in sensorList"
            :key="item.sensorId"
            :label="$t('port')+':'+item.port + ' ['+item.sensorName+']'"
            :value="item.sensorId"
          />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-input
          v-model="name"
          clearable
          :placeholder="$t('name')"
          @change="listDeviceSetting"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" @click="listDeviceSetting">{{ $t('search') }}</el-button>
      </el-form-item>
    </el-form>

    <el-table
      ref="settingTable"
      highlight-current-row
      :data="settingList"
      style="width: 100%"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="55" />
      <el-table-column prop="rankNumber" :label="$t('rankNumber')" width="50" />
      <el-table-column prop="productId" width="50">
        <template slot-scope="scope">
          <el-image
            :src="scope.row.iconUrl"
            :preview-src-list="[scope.row.iconUrl]"
            style="width: 20px;height: 20px;margin-top: 5px"
          />
        </template>
      </el-table-column>
      <el-table-column prop="name" :label="$t('name')" />
      <el-table-column prop="remark" :label="$t('remark')" />
      <el-table-column :label="$t('value')">
        <template slot-scope="scope">
          <div v-if="scope.row.type === 'fixedParam' && scope.row.paramList && scope.row.paramList.length > 0">
            <span
              v-for="(param,index) in scope.row.paramList"
              v-if="param.value === scope.row.value"
              :key="index"
            >{{ param.name }} <span>({{ param.value }})</span></span>
          </div>
          <span v-else-if="scope.row.type === 'switch'">{{ scope.row.value === '1' ? $t('open') :$t('close') }} <span>({{ scope.row.value }})</span></span>
          <span v-else>{{ scope.row.value }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="unit" :label="$t('unit')" />
      <el-table-column :label="$t('hidden')" width="100">
        <template slot-scope="scope">
          <el-switch
            v-model="scope.row.hidden"
            @change="hidden(scope.row)"
          />
        </template>
      </el-table-column>
      <el-table-column :label="$t('disabled')" width="100">
        <template slot-scope="scope">
          <el-switch
            v-model="scope.row.disabled"
            @change="disabled(scope.row)"
          />
        </template>
      </el-table-column>
      <!--      <el-table-column :label="$t('device')+$t('linkage')" width="110" >-->
      <!--        <template slot-scope="scope">-->
      <!--          <el-switch-->
      <!--            v-model="scope.row.canDeviceLinkage"-->
      <!--            @change="canDeviceLinkage(scope.row)"-->
      <!--          />-->
      <!--        </template>-->
      <!--      </el-table-column>-->
      <el-table-column :label="$t('type')" width="100">
        <template slot-scope="scope">
          {{ formatSettingType(scope.row.type) }}
        </template>
      </el-table-column>
      <el-table-column :label="$t('function')" width="260">
        <template slot-scope="scope">
          <el-button
            v-if="scope.row.type === 'fixedParam' || scope.row.type === 'multiCustom'"
            type="text"
            icon="el-icon-thumb"
            @click.stop="showDeviceSettingParam(scope.row)"
          >{{ $t('param') }}
          </el-button>
          <el-button
            type="text"
            icon="el-icon-notebook-2"
            @click.stop="showValueHistory(scope.row)"
          >{{ $t('value')+$t('history') }}
          </el-button>
          <el-button
            type="text"
            icon="el-icon-edit"
            @click="edit(scope.row)"
          >{{ $t('edit') }}
          </el-button>
          <el-button
            style="color: #f56c6c"
            type="text"
            icon="el-icon-delete"
            @click="del(scope.row)"
          >{{ $t('delete') }}
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-dialog
      :visible.sync="dialogSettingFormVisible"
    >
      <el-form
        label-width="20%"
        :model="setting"
      >
        <el-form-item :label="$t('name')">
          <el-autocomplete
            v-model="setting.name"
            :disabled="setting.settingId > 0"
            :fetch-suggestions="nameSearch"
            clearable
            @select="nameChange"
          />
        </el-form-item>
        <el-form-item :label="$t('keyName')">
          <el-autocomplete
            v-model="setting.keyName"
            :disabled="setting.settingId > 0"
            :fetch-suggestions="keyNameSearch"
            clearable
            @select="keyNameChange"
          />
        </el-form-item>
        <el-form-item :label="$t('remark')">
          <el-input v-model="setting.remark" />
        </el-form-item>
        <el-form-item :label="$t('value')">
          <div v-if="setting.type === 'fixedParam'">
            <el-select
              v-model="setting.value"
            >
              <el-option
                v-for="item2 in setting.paramList"
                :key="item2.value"
                :label="item2.name"
                :value="item2.value"
              />
            </el-select>
          </div>
          <div v-else-if="setting.type === 'switch'">
            <el-switch
              v-model="setting.value"
              :active-text="$t('open')"
              :inactive-text="$t('close')"
              active-value="1"
              inactive-value="0"
            />
          </div>
          <div v-else-if="setting.type === 'time'">
            <el-time-picker
              v-model="setting.value"
              value-format="HH:mm"
              format="HH:mm"
            />
          </div>
          <div v-else-if="setting.type === 'timeSlot'">
            <time-slot v-model="setting.value" />
          </div>
          <div v-else-if="setting.type === 'slider'">
            <el-slider
              v-model="setting.value"
            />
          </div>
          <div v-else="">
            <el-input
              v-model="setting.value"
            />
          </div>
        </el-form-item>
        <el-form-item v-if="setting.type === 'multiCustom'" :label="$t('type')">
          <el-tag
            v-for="(typeRule,index) in setting.typeRuleList"
            :key="typeRule"
            size="medium"
            style="margin-right: 5px"
            closable
            @close="deleteTypeRule(index)"
          >
            {{ formatSettingType(typeRule) }}
          </el-tag>
          <el-select v-if="showTypeRuleSelect" v-model="typeRuleValue" @change="typeRuleSelect">
            <el-option
              v-for="item in settingTypeList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
              :disabled="item.value === 'customProtocol' || item.value === 'noParam' || item.value === 'multiCustom'"
            />
          </el-select>
          <el-button v-else type="text" icon="el-icon-plus" @click="showTypeRuleSelect = true" />
        </el-form-item>
        <el-form-item :label="$t('unit')">
          <el-input v-model="setting.unit" />
        </el-form-item>
        <el-form-item :label="$t('rankNumber')">
          <el-input v-model="setting.rankNumber" />
        </el-form-item>
        <el-form-item :label="$t('regex')">
          <el-input v-model="setting.valueRegex" />
        </el-form-item>
        <el-form-item :label="$t('icon')">
          <el-input v-model="setting.iconUrl">
            <template slot="prepend">
              <el-image
                style="width: 20px;height: 20px;margin-top: 2px"
                :src="setting.iconUrl"
              />
            </template>
            <template slot="append">
              <i class="el-icon-caret-bottom" @click="choseIcon" />
            </template>
          </el-input>
          <div v-show="isIconOpen">
            <el-image
              v-for="(item,index) in iconList"
              :key="index"
              style="margin: 5px;cursor: pointer;width: 40px;height: 40px"
              :src="item.url"
              @click="changeIco(item.url,200145308)"
            />
          </div>
        </el-form-item>
        <el-form-item :label="$t('type')">
          <el-select
            v-model="setting.type"
            clearable
            @change="typeChange"
          >
            <el-option
              v-for="(item,index) in settingTypeList"
              :key="index"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item :label="$t('device')+$t('linkage')">
          <el-switch
            v-model="setting.canDeviceLinkage"
            :active-text="$t('open')"
            :inactive-text="$t('close')"
          />
        </el-form-item>
        <el-form-item :label="$t('hidden')">
          <el-switch
            v-model="setting.hidden"
            :active-text="$t('open')"
            :inactive-text="$t('close')"
          />
        </el-form-item>
        <el-form-item :label="$t('disabled')">
          <el-switch
            v-model="setting.disabled"
            :active-text="$t('open')"
            :inactive-text="$t('close')"
          />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogSettingFormVisible = false">{{ $t('cancel') }}</el-button>
        <el-button type="primary" @click="addOrUpdate">{{ $t('confirm') }}</el-button>
      </div>
    </el-dialog>

    <el-dialog
      :title="$t('param')"
      :visible.sync="dialogParamListVisible"
    >
      <device-param v-if="dialogParamListVisible" :setting="setting" />
    </el-dialog>

    <el-dialog
      :title="$t('history')"
      width="800px"
      :visible.sync="dialogValueHistoryVisible"
    >
      <value-history v-if="dialogValueHistoryVisible" :setting="setting" />
    </el-dialog>

    <el-dialog
      :visible.sync="showSetting"
      :title="deviceName"
      destroy-on-close
      width="1200px"
      top="15px"
    >
      <device-setting :device-core="deviceCore" :sensor-id="sensor.sensorId" />
    </el-dialog>
  </div>
</template>

<script>
import Sortable from 'sortablejs'
import {
  failureNotice,
  successNotice,
  cancelNotice,
  formatSettingType,
  listSettingType,
  formatDeviceSetting
} from '@/util/common'
import {
  deleteDeviceSetting,
  updateDeviceSetting,
  insertDeviceSetting,
  deleteDeviceSettingList,
  updateDeviceSettingList,
  listDeviceSettingIcon, listDeviceSetting
} from '@/api/iot/iotDeviceSettingApi'
import {
  listSensorWith
} from '@/api/iot/iotDeviceSensorApi'
import { listProductTemplateSetting } from '@/api/iot/iotProductTemplateSettingApi'
import DeviceSetting from '@/components/DeviceSetting'
import TimeSlot from '@/components/TimeSlot'
import DeviceParam from './DeviceParam'
import ValueHistory from './ValueHistory'

export default {
  name: 'SettingManage',
  components: {
    TimeSlot,
    DeviceSetting,
    DeviceParam,
    ValueHistory
  },
  data() {
    return {
      iconList: [],
      setting: {},
      sensorList: [],
      sensor: {},
      sensorId: null,
      name: null,
      settingList: [],
      dialogSettingFormVisible: false,
      dialogParamListVisible: false,
      dialogValueHistoryVisible: false,
      settingParameter: null,
      productTemplateList: [],
      isIconOpen: false,
      deviceName: null,
      deviceCore: null,
      mList: [],
      showSetting: false,
      settingTypeList: [],
      nameList: [],
      keyNameList: [],
      showTypeRuleSelect: false,
      typeRuleValue: null
    }
  },
  mounted() {
    const param = this.$route.query
    this.deviceCore = param.deviceCore
    this.deviceName = param.deviceName
    this.sensorId = param.sensorId ? parseInt(param.sensorId) : null
    this.settingTypeList = listSettingType(this)
    this.listSensorWith()
    this.listProductTemplateSetting()
    this.listDeviceSettingIcon()
    this.setTagsViewTitle()
  },
  methods: {
    typeChange() {
      if (this.setting.type === 'timeSlot') {
        this.setting.value = '00:00 / 00:00'
      } else if (this.setting.type === 'time') {
        this.setting.value = '00:00'
      } else if (this.setting.type === 'switch') {
        this.setting.value = '0'
      } else if (this.setting.type === 'noParam') {
        this.setting.value = ''
      } else if (this.setting.type === 'slider') {
        this.setting.value = 0
      } else {
        this.setting.value = ''
      }
    },
    gotoVisible() {
      this.$router.push({
        path: '/device/setting/visible/' + this.deviceCore,
        query: {
          port: this.port,
          deviceName: this.deviceName,
          deviceCore: this.deviceCore
        }
      })
    },
    formatSettingType(type) {
      return formatSettingType(this, type)
    },
    typeRuleSelect() {
      this.setting.typeRuleList.push(this.typeRuleValue)
      this.typeRuleValue = null
    },
    deleteTypeRule(index) {
      this.setting.typeRuleList.splice(index, 1)
    },
    gotoSensor() {
      this.$router.push({
        path: '/device/sensor/' + this.deviceCore,
        query: { deviceCore: this.deviceCore, deviceName: this.deviceName }
      })
    },
    listDeviceSettingIcon() {
      listDeviceSettingIcon({}).then(res => {
        const { code, data } = res
        if (code === '200') {
          this.iconList = data
        }
      })
    },
    showDeviceSettingParam(item) {
      this.setting = item
      this.dialogParamListVisible = true
    },
    showValueHistory(item) {
      this.setting = item
      this.dialogValueHistoryVisible = true
    },
    createFilter(queryString) {
      return (restaurant) => {
        return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0)
      }
    },
    nameSearch(queryString, cb) {
      const nameList = this.nameList
      const results = queryString ? nameList.filter(this.createFilter(queryString)) : nameList
      cb(results)
    },
    keyNameSearch(queryString, cb) {
      const keyNameList = this.keyNameList
      const results = queryString ? keyNameList.filter(this.createFilter(queryString)) : keyNameList
      cb(results)
    },
    sensorChange() {
      this.sensorList.forEach(sensor => {
        if (this.sensorId === sensor.sensorId) {
          this.sensor = sensor
          const settingList = []
          if (this.name) {
            sensor.settingList.forEach(setting => {
              if (setting.name.indexOf(this.name) >= 0) {
                settingList.push(setting)
              }
            })
            this.settingList = settingList
          } else {
            this.settingList = sensor.settingList
          }
          this.$nextTick(() => {
            this.setSort()
          })
        }
      })
    },
    listSensorWith() {
      listSensorWith({
        deviceCore: this.deviceCore,
        withSetting: true,
        useVisible: false
      }).then(res => {
        const { code, data } = res
        if (code === '200') {
          this.sensorList = data
          let settingListRes
          if (this.sensorId) {
            data.forEach(sensor => {
              if (sensor.sensorId === this.sensorId) {
                this.sensor = sensor
                this.sensorId = this.sensor.sensorId
                settingListRes = sensor.settingList
              }
            })
          } else {
            this.sensor = data[0]
            this.sensorId = this.sensor.sensorId
            settingListRes = data[0].settingList
          }
          const settingList = []
          settingListRes.forEach(setting => {
            setting = formatDeviceSetting(setting)
            if (this.name && this.name !== '') {
              if (setting.name.indexOf(this.name) >= 0) {
                settingList.push(setting)
              }
            } else {
              settingList.push(setting)
            }
          })
          this.settingList = settingList
          this.$nextTick(() => {
            this.setSort()
          })
        } else {
          this.sensorList = []
          this.sensor = {}
        }
      })
    },
    listDeviceSetting() {
      this.settingList = []
      listDeviceSetting({
        sensorId: this.sensor.sensorId
      }).then(res => {
        const { code, data } = res
        if (code === '200') {
          this.settingList = data
          this.$nextTick(() => {
            this.setSort()
          })
        }
      })
    },
    setSort() {
      if (this.sortable) {
        this.sortable.closest()
      }
      const el = this.$refs.settingTable.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
      this.sortable = Sortable.create(el, {
        // ghostClass: 'sortable-ghost', // Class name for the drop placeholder,
        // setData(dataTransfer) {
        //   dataTransfer.setData('Text', '')
        // },
        onEnd: evt => {
          const targetRow = this.settingList.splice(evt.oldIndex, 1)[0]
          this.settingList.splice(evt.newIndex, 0, targetRow)
          const updateList = []
          for (let i = 0, j = this.settingList.length; i < j; i++) {
            const setting = this.settingList[i]
            updateList.push({
              rankNumber: i,
              settingId: setting.settingId
            })
          }

          updateDeviceSettingList({
            settingList: updateList
          }).then(res => {
            const { code } = res
            if (code === '200') {
              successNotice(this)
              this.listDeviceSetting()
            }
          })
        }
      })
    },
    mDel() {
      const that = this
      this.$confirm(this.$t('deletePrompt'), this.$t('prompt'), {
        confirmButtonText: this.$t('confirm'),
        cancelButtonText: this.$t('cancel'),
        type: 'warning'
      })
        .then(function() {
          deleteDeviceSettingList({
            idList: that.mList
          }).then(res => {
            const { code } = res
            if (code === '200') {
              that.listDeviceSetting()
            }
          })
        })
        .catch(function() {
          cancelNotice(that)
        })
    },
    handleSelectionChange(value) {
      const mList = []
      value.forEach(function(row) {
        mList.push(row.settingId)
      })
      this.mList = mList
    },
    setTagsViewTitle() {
      this.tempRoute = Object.assign({}, this.$route)
      const route = Object.assign({}, this.tempRoute, {
        title: `${this.deviceName}`
      })
      this.$store.dispatch('tagsView/updateVisitedView', route)
    },
    changeIco(iconUrl) {
      this.isIconOpen = false
      this.setting.iconUrl = iconUrl
    },
    choseIcon() {
      if (this.isIconOpen) {
        this.isIconOpen = false
      } else {
        this.isIconOpen = true
      }
    },
    nameChange(item) {
      this.setting.name = item.value
      for (let i = 0; i < this.productTemplateList.length; i++) {
        if (this.productTemplateList[i].name === item.value) {
          this.setting.keyName = this.productTemplateList[i].keyName
          this.setting.type = this.productTemplateList[i].type
          this.setting.iconUrl = this.productTemplateList[i].iconUrl
          this.setting.value = this.productTemplateList[i].value
          this.setting.unit = this.productTemplateList[i].unit
          this.setting.hidden = this.productTemplateList[i].hidden
          this.setting.disable = this.productTemplateList[i].disable
          this.setting.canDeviceLinkage = this.productTemplateList[i].canDeviceLinkage
          this.setting.rankNumber = this.productTemplateList[i].rankNumber
          break
        }
      }
    },
    keyNameChange(item) {
      this.setting.keyName = item.value
      for (let i = 0; i < this.productTemplateList.length; i++) {
        if (this.productTemplateList[i].keyName === item.value) {
          this.setting.name = this.productTemplateList[i].name
          this.setting.type = this.productTemplateList[i].type
          this.setting.iconUrl = this.productTemplateList[i].iconUrl
          this.setting.value = this.productTemplateList[i].value
          this.setting.unit = this.productTemplateList[i].unit
          this.setting.hidden = this.productTemplateList[i].hidden
          this.setting.disable = this.productTemplateList[i].disable
          this.setting.canDeviceLinkage = this.productTemplateList[i].canDeviceLinkage
          this.setting.rankNumber = this.productTemplateList[i].rankNumber
          break
        }
      }
    },
    listProductTemplateSetting() {
      listProductTemplateSetting({
        deviceCore: this.deviceCore
      }).then(res => {
        const { data, code } = res
        if (code === '200') {
          this.productTemplateList = data
          const nameList = []
          const keyNameList = []
          data.forEach(item => {
            nameList.push({ value: item.name })
            keyNameList.push({ value: item.keyName })
          })
          this.nameList = nameList
          this.keyNameList = keyNameList
        } else {
          this.productTemplateList = []
          this.nameList = []
          this.keyNameList = []
        }
      })
    },
    gotoHistory() {
      this.$router.push({
        path: '/device/setting/history/' + this.deviceCore,
        query: { deviceCore: this.deviceCore, deviceName: this.deviceName }
      })
    },
    showAdd() {
      this.setting = {
        port: this.sensor.port,
        deviceCore: this.deviceCore,
        type: 'custom',
        value: '',
        typeRuleList: [],
        hidden: false,
        disable: false,
        canDeviceLinkage: false
      }
      this.dialogSettingFormVisible = true
    },
    addOrUpdate() {
      const json = {
        ...this.setting
      }
      if (this.setting.settingId) {
        updateDeviceSetting(json).then(res => {
          const { code } = res
          if (code === '200') {
            this.dialogSettingFormVisible = false
            this.dialogParamListVisible = false
          }
          this.listDeviceSetting()
        })
      } else {
        if (!this.setting.name || this.setting.name === '') {
          failureNotice(this, this.$t('not') + this.$t('name'))
          return
        }
        insertDeviceSetting(json).then(res => {
          const { code } = res
          if (code === '200') {
            this.dialogSettingFormVisible = false
            this.dialogParamListVisible = false
          }
          this.listDeviceSetting()
        })
      }
    },
    edit(item) {
      this.setting = item
      this.dialogSettingFormVisible = true
    },
    del(item) {
      const that = this
      this.$confirm(this.$t('delete') + item.name, this.$t('prompt'), {
        confirmButtonText: this.$t('confirm'),
        cancelButtonText: this.$t('cancel'),
        type: 'warning'
      })
        .then(function() {
          deleteDeviceSetting({
            settingId: item.settingId
          }).then(res => {
            const { code } = res
            if (code === '200') {
              successNotice(that)
            }
            that.listDeviceSetting()
          })
        })
        .catch(function() {
          cancelNotice(that)
        })
    },
    hidden(item) {
      updateDeviceSetting({
        settingId: item.settingId,
        hidden: item.hidden
      }).then(res => {
        const { code } = res
        if (code === '200') {
          successNotice(this)
        }
        this.listDeviceSetting()
      })
    },
    canDeviceLinkage(item) {
      updateDeviceSetting({
        settingId: item.settingId,
        canDeviceLinkage: item.canDeviceLinkage
      }).then(res => {
        const { code } = res
        if (code === '200') {
          successNotice(this)
        }
        this.listDeviceSetting()
      })
    },
    disabled(item) {
      updateDeviceSetting({
        settingId: item.settingId,
        disabled: item.disabled
      }).then(res => {
        const { code } = res
        if (code === '200') {
          successNotice(this)
        }
        this.listDeviceSetting()
      })
    }
  }
}
</script>
